<!--
 * @name: 
 * @Author: JiaYing
 * @LastEditors: JiaYing
 * @Date: 2022-08-31 15:30:08
 * @LastEditTime: 2022-09-01 16:26:59
 * @Description: 
-->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>回流和重绘</title>
  </head>
  <style>
    .box {
      width: 100px;
      height: 100px;
      background-color: aquamarine;
    }
    .absolute {
      position: absolute;
    }

    .animation {
      animation: box 3s ease-in-out;
      animation-iteration-count: infinite;
    }
    @keyframes box {
      0% {
        transform: translateX(0);
      }
      50% {
        transform: translateX(800px);
      }
      100% {
        transform: translateX(0px);
      }
    }
  </style>
  <body>
    <p>
      <button onclick="control('s1')">S1</button>
      <button onclick="control('s2')">S2</button>
      <button onclick="control('s3')">S3</button>
    </p>
    <div class="box"></div>
  </body>
</html>

<script>
  (function () {
    function s1() {
      const box = document.querySelector(".box");
      let step = 5;
      let range = [0, 800];
      let currstep = box.offsetLeft;
      let stop = false;
      box.classList.add("absolute");
      function run() {
        if (stop) return;
        currstep += step;
        if (currstep > range[1]) {
          currstep = range[1];
          step *= -1;
        } else if (currstep < range[0]) {
          currstep = range[0];
          step *= -1;
        }
        box.style.left = currstep + "px";
        requestAnimationFrame(run);
      }
      run();
      return {
        setStop(v) {
          stop = v;
          box.style.left = null;
          box.classList.remove("absolute");
        },
      };
    }

    function s2() {
      const box = document.querySelector(".box");
      let step = 5;
      let range = [0, 800];
      let currstep = box.offsetLeft;
      let stop = false;
      function run() {
        if (stop) return;
        currstep += step;
        if (currstep > range[1]) {
          currstep = range[1];
          step *= -1;
        } else if (currstep < range[0]) {
          currstep = range[0];
          step *= -1;
        }
        box.style.transform = `translateX(${currstep + "px"})`;
        requestAnimationFrame(run);
      }
      run();
      return {
        setStop(v) {
          stop = v;
          box.style.transform = null;
        },
      };
    }

    function s3() {
      const box = document.querySelector(".box");
      box.classList.add("animation");
      return {
        setStop(v) {
          v
            ? box.classList.remove("animation")
            : box.classList.add("animation");
        },
      };
    }
    window.s3 = s3;

    window.s1 = s1;
    window.s2 = s2;

    var control = (function () {
      let ctx = null;
      return function (fnName) {
        if (
          !fnName ||
          Object.prototype.hasOwnProperty.call(window, fnName) == false
        )
          return;
        if (ctx) {
          ctx.setStop(true);
        }
        ctx = window[fnName]();
      };
    })();
    window.control = control;
  })();
</script>
